package com.dingwen.treasure.kettle.base.convert.jackson;

import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonStreamContext;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.dingwen.treasure.kettle.base.enums.BaseEnum;
import com.dingwen.treasure.kettle.constant.SuppressWarningConstant;
import com.dingwen.treasure.kettle.exception.EnumMappingException;
import lombok.SneakyThrows;
import org.springframework.http.HttpStatus;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Field;

/**
 * 　AbstractEnumDeserializer
 * 　@author dingwen
 * 　@date 2022/6/15
 */
@SuppressWarnings(SuppressWarningConstant.ALL)
public class BaseEnumDeserializer<E extends BaseEnum> extends JsonDeserializer<E> {

    /**
     * 实例
     */
    public static final BaseEnumDeserializer INSTANCE = new BaseEnumDeserializer();

    private BaseEnumDeserializer() {
    }

    @SneakyThrows
    @Override
    public E deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) {
        JsonStreamContext parsingContext = jsonParser.getParsingContext();

        // 当前进行反序列化的对象
        Object contentObject = parsingContext.getCurrentValue();

        //当前进行序列化的字段
        String currentName = parsingContext.getCurrentName();
        Field field = ReflectionUtils.findField(contentObject.getClass(), currentName);

        // 当前属性的枚举类型
        assert field != null;
        Class<E> enumClass = (Class<E>) field.getType();
        return parse(jsonParser.getValueAsString(), enumClass);
    }

    /**
     * 枚举转换
     *
     * @param code code
     * @return 枚举
     */
    E parse(String code, Class<E> eClass) {
        for (E e : eClass.getEnumConstants()) {
            if (e.getCode().toString().equals(code)) {
                return e;
            }
        }
        String message = StrUtil.format("枚举类：{},不存在 code: {}", eClass.getSimpleName(), code);
        throw new EnumMappingException(HttpStatus.BAD_REQUEST.value(), message);
    }


}
